package com.ruoyi;

import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson.JSON;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class Test2 {
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static void main(String[] args) throws Exception {

        Map<String, Object> params = new HashMap<>();
        params.put("rand", "s2y5cxqigpp1q9bk");
        params.put("sign", "428bb8ce41864d4e");
        params.put("third_uid", "1693898750361079808"); // DigestUtil.md5Hex(appid + thirduid)
        params.put("timestamp", "1692718083");

//        params.put("rand", "wl4i22nxq29fzz1b");
//        params.put("sign", "660d9d5b7895d90c");
//        params.put("third_uid", "1693898750361079808"); // DigestUtil.md5Hex(appid + thirduid)
//        params.put("timestamp", "1692722168");




        String data = JSON.toJSONString(params);
        String key = "60320b424ff37e20"; //16位字符串密钥
        String iv = "57d5666692e6fe0c";//16位字符串偏移


        AES aes = new AES("CBC", "PKCS7Padding", key.getBytes(), iv.getBytes());
        String token2 = aes.encryptBase64(data); // 加密并进行Base转码
//
//
        System.out.println(token2);

        //加密数据
        String encodeResult = encryptAES(data,key,iv);
        System.out.println(String.format("aes-cbc-128加密结果 ->  %s",encodeResult));

        //解密数据
        String decodeResult = decryptAES(encodeResult,key,iv);
        System.out.println(String.format("解密结果: -> %s",decodeResult));

    }

    /**
     * 加密数据
     * @param data 明文内容
     * @param key 密钥
     * @param iv 偏移
     * @return
     */
    private static String encryptAES(String data,String key,String iv) {
        try {

            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"), new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)));
            byte[] result = cipher.doFinal(pkcs7padding(data, cipher.getBlockSize())); // 好气啊, 要自己手动实现 PKCS7Padding 填充
            return Base64.getEncoder().encodeToString(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "NULL";
    }

    /**
     * 解密数据
     * @param data 加密内容
     * @param key 密钥
     * @param iv 偏移
     * @return
     */
    private static String decryptAES(String data, String key,String iv) {
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"), new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)));
            byte[] result = cipher.doFinal(Base64.getDecoder().decode(data));
            return new String(result, StandardCharsets.UTF_8).trim();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "NULL";
    }

    /**
     * pkcs7填充
     * @param content
     * @param blockSize
     * @return
     */
    private static byte[] pkcs7padding(String content, int blockSize) {
        byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
        int pad = blockSize - (contentBytes.length % blockSize); // 计算需要补位的长度
        byte padChr = (byte) pad; // 补位字符 (即用补位长度)
        byte[] paddedBytes = new byte[contentBytes.length + pad]; // 在原有的长度上加上补位长度
        System.arraycopy(contentBytes, 0, paddedBytes, 0, contentBytes.length); // 原有的先复制过去
        for (int i = contentBytes.length; i < paddedBytes.length; i++) { // 补位字符填充
            paddedBytes[i] = padChr;
        }
        return paddedBytes;
    }
}
